# Create your views here.
from django.http import HttpResponse
from django.template.loader import render_to_string
from django.contrib.auth.decorators import login_required
from django.http import Http404
from iperscribo.pages.models import Page, Revision, Tag
from iperscribo.projects.models import Project, Activity, OBJECT_TYPE, ACTION_TYPE
from django.contrib.auth.models import User
from django.contrib.auth import logout
from iperscribo.thirdparty.decorators import json_view, deprecated
from iperscribo.thirdparty.diff_match_patch import diff_match_patch
from iperscribo.thirdparty.ordereddict import OrderedDict
from django.utils import simplejson
from django.conf import settings
import Queue
from iperscribo.thirdparty.djangologging import debug, info, error, warn

#################################################################################################################################################


@deprecated
@login_required
def openpage(request, projectname, pagepath):

    new_page = False

    #retrieve current project
    project = Project.objects.filter(name=projectname)
    if not project:
        raise Http404
    else:
        current_project = project[0]
        
    #retrieve current user
    
    user = request.user


    page = Page.objects.filter(project=current_project, path=pagepath)
    if not page:
        new_page = True
        current_page = Page()
        parent_revision_uid = 0
        current_tag = Tag()
        text = 'insert text here'
    else:
        #Carico la pagina dal database
        current_page = page[0]
        #Cerca il tag corrente [per adesso il draft, che se esiste la pagina deve esistere]
        current_tag = Tag.objects.filter(page=current_page, name='draft')[0]
        parent_revision_uid=current_tag.revision.uid
        text = current_tag.text
        

        
    #Se non esiste la pagina la devo creare. Comporta creare l'id della pagina e il tag. 
    #Make new Page
    
    
    
    #Se la pagina esiste, devo recuperare il parent_ID per quell'utente se esiste, altrimenti l'id della versione 
    #pubblica. Semplifichiamo il tutto. Per adesso revisioni come google docs.



    return HttpResponse(render_to_string('pages/editor.html', { 
        
        'parent_revision_uid': parent_revision_uid, 
        'tag_uid' : current_tag.uid,
        'page_uid' : current_page.uid,
        'page_path' : pagepath,
        'project_uid' : current_project.uid, 
        'text' : text,
    })) 

#################################################################################################################################################

@login_required
def openpagehistory(request, projectname, pagepath):
    
    current_project = Project.objects.get(name=projectname)
    revisions = Revision.objects.filter(page=Page.objects.get(path = pagepath, project = current_project)).order_by('-pid')[:40]
    
    return HttpResponse(render_to_string('pages/history.html', {'project_uid': current_project.uid, 'pagepath' : pagepath, 'revisions' : revisions}))

#################################################################################################################################################

@login_required
def openrevision(request, project_uid, revision_uid):

    diff_engine = diff_match_patch()

    request_revision = Revision.objects.get(uid=revision_uid)
    
    changes = OrderedDict()
    complete_changeset = False
    current_revision = request_revision
    #Recupero le revisioni necessarie
    while not complete_changeset:
        print 'searching'
        changes[current_revision.uid] = current_revision.changes
        
        if current_revision.parents.count() != 1:
            complete_changeset = True
        else:
            current_revision = current_revision.parents.all()[0]
    
    result = ''
    
    #Applico le patch fino a ricreare la revisione necessaria
    for i in range(len(changes)):
        
        print 'applying'
        patches_txt = changes.popitem(True)[1]
        patches = diff_engine.patch_fromText(patches_txt)
        result = diff_engine.patch_apply(patches, result)[0]
        print 'result: ', result
    
    return HttpResponse(render_to_string('pages/revision.html', {'text': result}))

#################################################################################################################################################

@login_required
@json_view
def save(request, tag_uid):
    
    debug('in save view')
    #test()
    
    try:
        text = request.POST['text']
        previous_tag = Tag.objects.get(uid=tag_uid)
        current_page = previous_tag.page
        diff_engine = diff_match_patch()
        changes = diff_engine.patch_toText(diff_engine.patch_make(previous_tag.text, text))
        
        if changes:
            current_revision = Revision(page=current_page, owner=request.user, changes=changes)
            current_revision.parents.add(previous_tag.revision)
            current_revision.save()
            current_tag = previous_tag
            current_tag.revision = current_revision
            current_tag.text = text
            current_tag.save()
            
            #Add Activity
            Activity(type = '0', action = '1', user = request.user, object_uid = current_page.uid).save()
            
            return {'message' : 'DONE', 'parent_revision_uid' : current_revision.uid, 'tag_uid' : current_tag.uid}
        else:
            return {'message' : 'NOTHING', 'parent_revision_uid' : previous_tag.revision.uid, 'tag_uid' : previous_tag.uid}
    except Exception, ex:
        error(ex)
        raise ex

#################################################################################################################################################

@login_required
def add(request, project_name, page_path):
    
    current_project = Project.objects.get(name = project_name)
    if len(Page.objects.filter(path = page_path, project = current_project)) > 0:
        return HttpResponse('Error: page already exists')
    
    else:
        current_page = Page(owner=request.user, project=current_project, path=page_path)
        current_revision = Revision(page=current_page, owner=request.user, changes='')
        current_revision.save()
        current_page.save()
        
        current_tag = Tag(name='draft', page=current_page, revision=current_revision, text='', owner=request.user)
        current_tag.save()
        return HttpResponse('Done: page %s created' % page_path)
    
    
#################################################################################################################################################



@deprecated
@login_required
@json_view
def savepage(request, project_uid, page_uid):

    try:
        #Recupero il project su cui stiamo lavorando
        current_project = Project.objects.get(uid=project_uid)
        elements = dict(request.POST)
        print elements
        print type(elements)
        #elements = simplejson.loads(elements)
        print elements['tag_uid']
        print type(elements['tag_uid'])
        
        #Inizializzo il motore di diff
        diff_engine = diff_match_patch()
        
        #Se viene passata una revision_id la pagina esiste gia.
        #se viene passata anche una tag_id esiste il tag con il merge dei singoli diff gia pronto.
        
        #Se la pagina non esiste:
        if elements['parent_revision_uid'][0] == '0':
            print 'NEW PAGE'
            
            changes = diff_engine.patch_toText(diff_engine.patch_make('', elements['text'][0]))
            
            current_page = Page(owner=request.user, uid=page_uid, project=current_project, path=elements['page_path'][0])
            current_revision = Revision(page=current_page, owner=request.user, changes=changes)
            current_revision.save()
            current_page.root_revision = current_revision
            current_page.save()
            
            current_tag = Tag(uid=elements['tag_uid'][0], name='draft', page=current_page, revision=current_revision, text=elements['text'][0], owner=request.user)
            current_tag.save()

            print 'SAVE'
            
        #Se esiste:
        else:
            print 'OLD PAGE NEW REVISION'
            #Recuperiamo il tag in maniera da poter calcolare il diff
            print 'before previous tag', elements['tag_uid'][0]
            previous_tag = Tag.objects.get(uid=elements['tag_uid'][0])
            print previous_tag
            #calcoliamo i cambiamenti:
            changes = diff_engine.patch_toText(diff_engine.patch_make(previous_tag.text, elements['text'][0]))
            #Creo una nuova revisione ed imposto come parent della revisione quello passato dall'editor.
            #recupero la parent_revision
            print 'parent_revision_uid:%s' % elements['parent_revision_uid'][0]
            parent_revision = Revision.objects.get(uid=elements['parent_revision_uid'][0])
            current_revision = Revision(page=parent_revision.page, owner=request.user, changes=changes)
            current_revision.parents.add(parent_revision)
            current_revision.save()
            current_tag = previous_tag
            current_tag.revision = current_revision
            current_tag.text = elements['text'][0]
            current_tag.save()
            print current_revision
            print 'UPDATE'
    except Exception, ex:
        print ex
    
    return {'message' : 'Done', 'parent_revision_uid' : current_revision.uid, 'tag_uid' : current_tag.uid}

#################################################################################################################################################

@login_required
def view_editor(request, page_uid):
    current_page = Page.objects.get(uid=page_uid)
    
    return HttpResponse(render_to_string('pages/neweditor.html', {'page_uid': page_uid, 'tag_name' : 'draft'}))
#################################################################################################################################################

@login_required
def view_editor_frame(request, page_uid, tag_name):
    try:
        current_page = Page.objects.get(uid=page_uid)
        
        current_tag = Tag.objects.get(page=current_page, name=tag_name)
        current_revision = current_tag.revision
        result_text = current_tag.text
    except Exception, ex:
        result_text = ''
    return HttpResponse(render_to_string('pages/editorframe.html', {
                                                                        'text': result_text,
                                                                        'tag_uid' : current_tag.uid,
                                                                    }))

#################################################################################################################################################

@login_required
@json_view
def get_content(request, project_uid, page_uid, tag_name):
    
    current_project = Project.objects.get(uid=project_uid)
    current_page = Page.objects.get(uid=page_uid, project=current_project)
    current_tag = Tag.objects.get(page=current_page, name=tag_name)
    
    return {'content': current_tag.text, 'tag_uid' : current_tag.uid}

